using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System.Json;
using Android.Graphics;
using Android.Views.Animations;
using Tsanie.Common;
using Java.IO;
using System.Threading;

namespace Wallpaper
{
    class PreviewListAdapter : BaseAdapter, Android.Widget.AbsListView.IOnScrollListener, ISerializable
    {
        JsonArray pictures;
        Bitmap[] bitmaps;
        MainActivity main;

        public JsonArray Pictures { get { return pictures; } }

        public PreviewListAdapter(JsonArray result, MainActivity main)
        {
            this.main = main;
            Read(result);
        }

        public void Read(JsonArray result)
        {
            this.pictures = result;
            this.bitmaps = new Bitmap[result.Count];
            this.NotifyDataSetChanged();
        }

        public void Add(JsonArray result)
        {
            if (this.pictures == null || this.bitmaps == null)
            {
                Read(result);
                return;
            }

            try
            {
                var pics = new JsonArray((IEnumerable<JsonValue>)this.pictures);
                pics.AddRange((IEnumerable<JsonValue>)result);

                var bmps = new Bitmap[pics.Count];
                Array.Copy(this.bitmaps, bmps, this.bitmaps.Length);

                this.pictures = pics;
                this.bitmaps = bmps;
                this.NotifyDataSetChanged();
            }
            catch
            {
            }
        }

        #region - base adapter -

        public override int Count
        {
            get { return pictures.Count; }
        }

        public override Java.Lang.Object GetItem(int position)
        {
            return position;
        }

        public override long GetItemId(int position)
        {
            return position;
        }

        #endregion

        void LoadBitmap(Holder holder, Bitmap bmp)
        {
            int duration = main.Resources.GetInteger(Android.Resource.Integer.ConfigShortAnimTime);

            var alpha = new AlphaAnimation(0, 1);
            alpha.Duration = duration;
            holder.imagePreview.StartAnimation(alpha);
            holder.imagePreview.SetImageBitmap(bmp);

            alpha = new AlphaAnimation(1, 0);
            alpha.Duration = duration;
            alpha.AnimationEnd += delegate { holder.progress.Visibility = ViewStates.Gone; };
            holder.progress.StartAnimation(alpha);
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            Holder holder;
            if (convertView == null)
            {
                var flater = LayoutInflater.From(main);
                convertView = flater.Inflate(Resource.Layout.item, null);
                holder = new Holder
                {
                    textSize = convertView.FindViewById<TextView>(Resource.Id.textSize),
                    textTag = convertView.FindViewById<TextView>(Resource.Id.textTag),
                    imagePreview = convertView.FindViewById<ImageView>(Resource.Id.imagePreview),
                    progress = convertView.FindViewById(Resource.Id.progressPreview)
                };
                convertView.Tag = holder;
            }
            else
            {
                holder = (Holder)convertView.Tag;
            }

            var val = pictures[position];
            holder.textSize.Text = string.Format("{0}x{1}", val["width"], val["height"]);
            holder.textTag.Text = "tags: " + val["tags"];
            holder.tagPosition = position;
            holder.imagePreview.SetImageBitmap(null);
            var bmp = bitmaps[position];
            if (bmp != null)
            {
                holder.progress.Alpha = 0;
                holder.progress.Visibility = ViewStates.Gone;
                // cache
                //LoadBitmap(holder, bmp, false);
                holder.imagePreview.SetImageBitmap(bmp);
            }
            else
            {
                holder.progress.Alpha = 1;
                holder.progress.Visibility = ViewStates.Visible;
                string url = val["preview_url"];
                ThreadPool.QueueUserWorkItem(DownloadPreview, new object[]
                {
                    url,
                    position,
                    holder
                });
            }

            return convertView;
        }

        void DownloadPreview(object obj)
        {
            object[] os = (object[])obj;
            string url = (string)os[0];
            int position = (int)os[1];
            Holder holder = (Holder)os[2];

            byte[] data = new NetUtility { URL = url }.GetData();
            var bmp = BitmapFactory.DecodeByteArray(data, 0, data.Length);
            if (position < bitmaps.Length)
            {
                bitmaps[position] = bmp;
                if (position == holder.tagPosition)
                {
                    try
                    {
                        holder.imagePreview.Post(delegate
                        {
                            LoadBitmap(holder, bmp);
                        });
                    }
                    catch { }
                }
            }
        }

        class Holder : Java.Lang.Object
        {
            public int tagPosition;
            public TextView textSize;
            public TextView textTag;
            public ImageView imagePreview;
            public View progress;
        }

        int firstItemIndex;
        ScrollState scrollState;

        public int FirstItemIndex { get { return firstItemIndex; } }
        public ScrollState ScrollState { get { return scrollState; } }

        public void OnScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
        {
            if (pictures.Count > 0 && (firstVisibleItem + visibleItemCount >= totalItemCount))
            {
                main.LoadMorePreviews();
            }
            this.firstItemIndex = firstVisibleItem;
        }

        public void OnScrollStateChanged(AbsListView view, ScrollState scrollState)
        {
            this.scrollState = scrollState;
        }
    }
}